﻿//TODO: Test, EstimateBackgroundByUsingEdges

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// Estimate BoundingBox by using edges
    /// </summary>
    public class EstimateBoundingBoxByUsingEdges : BaseImageFilter
    {
        protected Color m_ColorReplace = Color.Transparent;

        /// <summary>
        /// Default constructor
        /// </summary>
        public EstimateBoundingBoxByUsingEdges()
            : this(Color.Blue)
        {
        }

        /// <summary>
        /// Specify color to replace
        /// </summary>
        /// <param name="_colorReplace"></param>
        public EstimateBoundingBoxByUsingEdges(Color _colorReplace)
        {
            m_ColorReplace = _colorReplace;
        }

        /// <summary>
        /// used by clone to create a deep copy
        /// </summary>
        /// <param name="_estimateBoundingBoxByUsingEdges"></param>
        internal EstimateBoundingBoxByUsingEdges(EstimateBoundingBoxByUsingEdges _estimateBoundingBoxByUsingEdges)
        {
            this.m_ColorReplace = _estimateBoundingBoxByUsingEdges.m_ColorReplace;
        }

        /// <summary>
        /// gets or sets Color replace
        /// </summary>
        public Color ColorReplace
        {
            get { return m_ColorReplace; }
            set { m_ColorReplace = value; }
        }

        /// <summary>
        /// To use this filter, you should have already used an edge filter in pic to detect
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            UnsafeBitmap bitmap = _bitmap;
            Pen pen = new Pen(new SolidBrush(m_ColorReplace));
            Graphics graphics = Graphics.FromImage(bitmap.InternalBitmap);
            int x = 0;
            int y = 0;

            int nHeight = bitmap.Height;
            int nWidth = bitmap.Width;

            List<Color> aColor = new List<Color>();
            Color color = Color.Transparent;
            Color colorAverage = Color.Transparent;
            for (y = 0; y < nHeight; y++)
            {
                aColor.Clear();
                for (x = nWidth - 1; x >= 0; x--)
                {
                    color = bitmap.GetPixel(x, y);
                    aColor.Add(color);
                    colorAverage = ColorFunctions.AverageColor(aColor);

                    if (color != colorAverage)
                    {
                        int nDistance = ColorFunctions.Distance(color, colorAverage);
                        if (nDistance > 200)
                        {
                            //TODO: speed this up by using UnsafeGraphics if it works correctly
                            bitmap.UnlockImage();
                            graphics.DrawLine(pen, x, y, x + aColor.Count, y);
                            bitmap.LockImage();
                            aColor.Clear();
                            break;
                        }
                    }
                    else
                    {
                        bitmap.SetPixel(x, y, Color.Black);
                    }
                }
            }
            return _bitmap;
        }

        /// <summary>
        /// Use this to create a deep copy
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new EstimateBoundingBoxByUsingEdges(this);
        }
    }
}